package com.xbongbong.crm.perform.query.list.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.crm.help.WorkReportHelp;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasListGroupEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.BelongEnum;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.BusinessListHelp;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasListGroupModel;
import com.xbongbong.paas.pojo.ButtonPojo;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.DepartmentVO;
import com.xbongbong.paas.toolbox.wrap.RoleSimpleVO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.parent.interfaces.WorkReportCommunicateListService;
import com.xbongbong.parent.pojo.list.ButtonPermissionPojo;
import com.xbongbong.parent.pojo.list.FieldListPojo;
import com.xbongbong.parent.pojo.list.WorkReportAnalysisVO;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.constant.RangeScreenConstant;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.WorkReportEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.formexplain.pojo.HandleExplainPojo;
import com.xbongbong.pro.permission.pojo.dto.VerifyViewPermissionDTO;
import com.xbongbong.pro.weblist.pojo.WorkReportPojo;
import com.xbongbong.pro.weblist.pojo.dto.WorkReportListDTO;
import com.xbongbong.pro.weblist.pojo.vo.WorkReportVO;
import com.xbongbong.pro.workreportset.pojo.WorkReportSetVisibleRange;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.WorkReportApprovePeopleEntity;
import com.xbongbong.saas.domain.entity.WorkReportCcEntity;
import com.xbongbong.saas.enums.ListGroupEnum;
import com.xbongbong.saas.enums.ListTopButtonEnum;
import com.xbongbong.saas.enums.SaasButtonEnum;
import com.xbongbong.saas.enums.SaasSubButtonEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.WorkReportDailyEnum;
import com.xbongbong.saas.enums.business.WorkReportFieldEnum;
import com.xbongbong.saas.model.WorkReportApprovePeopleModel;
import com.xbongbong.saas.model.WorkReportCcModel;
import com.xbongbong.saas.service.toolbox.help.SaasListDataPermissionHelp;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.help.ProPermissionHelp;
import com.xbongbong.sys.model.UserModel;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static com.xbongbong.paas.elasticsearch.constant.EsNormalConstant.MINI_MUM_SHOULD_MATCH;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchPhraseQuery;
import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author sunshaoxiang
 * @ClassName WorkReportListServiceImpl
 * @Description 工作报告列表页 业务层
 * @Date 2022/6/7 16:13
 * @Version 1.0
 **/
@Service("workReportListServiceImpl")
public class WorkReportListServiceImpl implements WorkReportCommunicateListService {

    public static final Logger LOGGER = LoggerFactory.getLogger(WorkReportListServiceImpl.class);

    @Resource
    private SaasListDataPermissionHelp saasListDataPermissionHelp;
    @Resource
    private UserModel userModel;
    @Resource
    private PaasListGroupModel paasListGroupModel;
    @Resource
    private WorkReportApprovePeopleModel workReportApprovePeopleModel;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;

    @Resource
    private WorkReportCcModel workReportCcModel;
    @Resource
    private WorkReportHelp workReportHelp;
    @Resource
    private BusinessListHelp businessListHelp;

    @Override
    public WorkReportVO list(WorkReportListDTO workReportListDTO) throws XbbException {
        //权限校验
        checkPermission(workReportListDTO);
        //获取数据
        WorkReportAnalysisVO workReportAnalysisVO = getData(workReportListDTO);
        //设置权限按钮
        UserEntity userEntity = userModel.getByKey(workReportListDTO.getUserId(),workReportListDTO.getCorpid());
        ButtonPermissionPojo buttonPermissionPojo = handlePermissionButton(workReportListDTO.getBusinessType(), workReportListDTO.getLoginUser(), userEntity);

        //封装并返回VO给前端
        return getReturnVO(workReportAnalysisVO.getWorkReportPojos(), workReportAnalysisVO.getTotalElements(), workReportListDTO.getPage(), workReportListDTO.getPageSize(), buttonPermissionPojo);
    }



    @Override
    public PaasFormEntityExt getForm(Long formId, String corpid) throws XbbException {
        return null;
    }

    @Override
    public HandleExplainPojo getExplain(FieldListPojo fieldListPojo) throws XbbException {
        return null;
    }

    @Override
    public WorkReportAnalysisVO getData(WorkReportListDTO workReportListDTO) throws XbbException {
        WorkReportAnalysisVO workReportAnalysisVO = new WorkReportAnalysisVO();
        //获取数据前置处理
        beforeGetDataHandle(workReportListDTO);
        //Es查询数据
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = getDataByEs(workReportListDTO);
        //数据解析
        List<WorkReportPojo> workReportPojos = analysisData(workReportListDTO,esEntities.getContent());

        workReportAnalysisVO.setTotalElements(esEntities.getTotalElements());
        workReportAnalysisVO.setWorkReportPojos(workReportPojos);
        return workReportAnalysisVO;
    }

    /**
     * 数据解析
     * @param workReportListDTO
     * @param paasFormDataEntityExts
     * @return
     */
    private List<WorkReportPojo> analysisData(WorkReportListDTO workReportListDTO, List<PaasFormDataEntityExt> paasFormDataEntityExts) {
        List<WorkReportPojo> workReportPojos = new ArrayList<>();
        String corpid = workReportListDTO.getCorpid();
        Set<String> userIdSet = new HashSet<>();
        for (PaasFormDataEntityExt entity : paasFormDataEntityExts){
            userIdSet.add(entity.getCreatorId());
        }
        Map<String,String> nameMap = userModel.getUserNameMap(corpid,new ArrayList<>(userIdSet),BasicConstant.ZERO);
        paasFormDataEntityExts.forEach(paasFormDataEntityExt -> {
            WorkReportPojo workReportPojo = analysisSingleData(paasFormDataEntityExt, nameMap, workReportListDTO.getUserId());
            if (workReportPojo != null) {
                workReportPojos.add(workReportPojo);
            }
        });

        return workReportPojos;
    }

    /**
     * 解析单条数据
     * @param entity
     * @param nameMap
     * @param userId
     * @return
     */
    private WorkReportPojo analysisSingleData(PaasFormDataEntityExt entity, Map<String, String> nameMap, String userId) {
        WorkReportPojo workReportPojo = new WorkReportPojo();
        JSONObject data = entity.getData();
        try {
            workReportPojo.setId(entity.getId());
            workReportPojo.setContent(data.getString(WorkReportFieldEnum.CONTENT.getAttr()));
            workReportPojo.setReportDate(DateUtil.getString(data.getInteger(WorkReportFieldEnum.REPORT_DATE.getAttr()),new SimpleDateFormat("yyyy-MM-dd")));
            workReportPojo.setUserName(nameMap.get(entity.getCreatorId()));
            workReportPojo.setIsReissue(data.getInteger(WorkReportFieldEnum.IS_RESSUE.getAttr()));
            workReportPojo.setUpdateTime(DateUtil.getString(entity.getUpdateTime().intValue(),new SimpleDateFormat("yyyy-MM-dd")));
            workReportPojo.setType(data.getInteger(WorkReportFieldEnum.TYPE.getAttr()));
            workReportPojo.setAddTime(entity.getAddTime());
            JSONArray reviewer = data.getJSONArray(WorkReportFieldEnum.REVIEWER.getAttr());
            workReportPojo.setReviewerNum(reviewer == null ? 0 : reviewer.size());
            Boolean isReview = false;
            if (reviewer != null){
                //TODO haibin.zhang 先没有灵魂的抄过来了，丑陋
                for (Object obj : reviewer){
                    JSONObject json = (JSONObject) obj;
                    if (Objects.equals(json.get("userId"),userId)){
                        isReview = true;
                        break;
                    }
                }
            }
            workReportPojo.setIsReview(isReview);
            workReportPojo.setIsMyReport(Objects.equals(userId,entity.getCreatorId()));
            return  workReportPojo;
        }catch (Exception e){

        }
        return  null;
    }

    /**
     * Es查询数据
     * @param workReportListDTO
     * @return
     */
    private XbbAggregatedPage<PaasFormDataEntityExt> getDataByEs(WorkReportListDTO workReportListDTO) throws XbbException {
        String corpid = workReportListDTO.getCorpid();
        String userId = workReportListDTO.getUserId();
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        Long listGroupId = workReportListDTO.getListGroupId();
        if (Objects.isNull(listGroupId)) {
            // 默认是全部的工作报告
            listGroupId = 0L;
        }
        List<String> checkUserIdIn = new ArrayList<>();
        if (workReportListDTO.getPid() != null && workReportListDTO.getTreeType() != null){
            if (Objects.equals("staff",workReportListDTO.getTreeType())){
                checkUserIdIn.add(workReportListDTO.getPid());
            }else if (Objects.equals("dep",workReportListDTO.getTreeType())){
                Long depId =StringUtil.StringToLong(workReportListDTO.getPid());
                checkUserIdIn = userModel.getUserIdsRecursionDep(Collections.singletonList(depId),corpid);
            }
        }
        // 分组
        if(listGroupId != null) {
            if (listGroupId != null && Objects.equals(workReportListDTO.getDefaultGroup(), 0)) {
                PaasListGroupEntity paasListGroupEntity = paasListGroupModel.getByKey(listGroupId, workReportListDTO.getCorpid());
                if (Objects.nonNull(paasListGroupEntity)) {
                    List<ConditionsEntityExt> listGroupConditionList = JSONArray.parseArray(paasListGroupEntity.getJsonData(), ConditionsEntityExt.class);
                    if (listGroupConditionList != null && !listGroupConditionList.isEmpty()) {
                        List<ConditionsEntityExt> conditionList = workReportListDTO.getConditions();
                        conditionList.addAll(listGroupConditionList);
                        workReportListDTO.setConditions(conditionList);
                    }
                }
            } else {
                ListGroupEnum listGroupEnum = ListGroupEnum.getByCode(listGroupId.intValue());
                UserEntity userEntity = userModel.getByKey(userId, corpid);
                String creatorAttr = FieldTypeEnum.CREATORID.getAlias() + ".keyword";

                List<Long> reportIdIn = new ArrayList<>();
                boolean needDataId = false;
                boolean shuoldDataId = false;
                switch (listGroupEnum){
                    case WORK_REPORT_SEND:
                        boolQueryBuilder.filter(termQuery(creatorAttr,userId));
                        break;
                    case WORK_REPORT_SEND_TO_ME:
                        Set<DepartmentVO> departmentVOSet = workReportListDTO.getLoginUser().getDepSet();
                        Set<RoleSimpleVO> roleSimpleVOSet = workReportListDTO.getLoginUser().getRoleSet();
                        List<String> deptIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        List<String> roleIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        List<String> userIds = Arrays.asList(userId);
                        if (!CollectionUtils.isEmpty(departmentVOSet)){
                            for (DepartmentVO item : departmentVOSet) {
                                deptIdIn.add(item.getId().toString());
                            }
                        }
                        if (!CollectionUtils.isEmpty(roleSimpleVOSet)){
                            for (RoleSimpleVO item : roleSimpleVOSet) {
                                roleIdIn.add(item.getId().toString());
                            }
                        }
                        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        map.put("corpid",corpid);
                        map.put("userIdIn",CollectionUtils.isEmpty(userIds) ? null : userIds);
                        map.put("deptIdIn",CollectionUtils.isEmpty(deptIdIn) ? null : deptIdIn);
                        map.put("roleIdIn",CollectionUtils.isEmpty(roleIdIn) ? null : roleIdIn);
                        map.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                        map.put("order by", "report_id desc");
                        // TODO 限制最大数
                        List<WorkReportApprovePeopleEntity> WorkReportApprovePeopleEntityList = workReportApprovePeopleModel.findEntitys(map);
                        for (WorkReportApprovePeopleEntity entity : WorkReportApprovePeopleEntityList){
                            reportIdIn.add(entity.getReportId());
                        }
                        needDataId = true;
                        Integer dataPermission = userModel.getDataPermission(userEntity, SaasMarkEnum.SAAS, XbbRefTypeEnum.WORK_REPORT.getCode(), null);
                        List<String> userIdIn = userModel.getSubIdListByDataPermission(dataPermission, userEntity.getUserId(), userEntity.getCorpid(), BasicConstant.ONE,false);
                        if (!checkUserIdIn.isEmpty()){
                            userIdIn.retainAll(checkUserIdIn);
                            userIdIn.add("-1");
                            boolQueryBuilder.filter(termsQuery(creatorAttr,userIdIn));
                        }
                        break;
                    case WORK_REPORT_COPY_TO_ME:
                        map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        map.put("corpid",corpid);
                        map.put("userId",userId);
                        map.put("columns", "report_id");
                        map.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                        map.put("order by", "report_id desc");
                        // TODO 限制最大数 注意：WorkReportCcEntity实体中只拿了report_id属性，没有其他属性
                        List<WorkReportCcEntity> workReportCcEntityList = workReportCcModel.findEntitys(map);
                        for (WorkReportCcEntity entity : workReportCcEntityList){
                            reportIdIn.add(entity.getReportId());
                        }
                        needDataId = true;
                        if (!checkUserIdIn.isEmpty()){
                            boolQueryBuilder.filter(termsQuery(creatorAttr,checkUserIdIn));
                        }
                        break;
                    default:
                        //产品说改为最大权限
                        if (!workReportListDTO.getLoginUser().isMaxDataPermission()){
                            Integer permission = userModel.getDataPermission(userEntity, SaasMarkEnum.SAAS, XbbRefTypeEnum.WORK_REPORT.getCode(), null);
                            userIdIn = userModel.getSubIdListByDataPermission(permission, userEntity.getUserId(), userEntity.getCorpid(),BasicConstant.ONE,false);
                            if (!checkUserIdIn.isEmpty()){
                                userIdIn.retainAll(checkUserIdIn);
                            }
                            map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                            map.put("corpid",corpid);
                            map.put("userId",userId);
                            map.put("columns", "report_id");
                            map.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                            //map.put("order by", "report_id desc");
                            // TODO 限制最大数 注意：WorkReportCcEntity实体中只拿了report_id属性，没有其他属性
                            workReportCcEntityList = workReportCcModel.findEntitys(map);
                            for (WorkReportCcEntity entity : workReportCcEntityList){
                                reportIdIn.add(entity.getReportId());
                            }
                            if (!reportIdIn.isEmpty() && !userIdIn.isEmpty()){
                                needDataId = true;
                                shuoldDataId = true;
                                boolQueryBuilder.should(termsQuery(creatorAttr,userIdIn));
                                boolQueryBuilder.minimumShouldMatch(MINI_MUM_SHOULD_MATCH);
                            }else if (!reportIdIn.isEmpty()){
                                needDataId = true;
                            } else if (!userIdIn.isEmpty()) {
                                boolQueryBuilder.filter(termsQuery(creatorAttr, userIdIn));
                            }else {
                                needDataId = true;
                                reportIdIn.clear();
                                reportIdIn.add(-1L);
                            }
                        } else {
                            if (!checkUserIdIn.isEmpty()){
                                boolQueryBuilder.filter(termsQuery(creatorAttr,checkUserIdIn));
                            }
                        }

                }

                // 数据id过长处理
                if (needDataId) {

                    List<Long> dataIdList = new ArrayList<>();
                    // es预查询，确保命中率
                    SearchSourceBuilder preSourceBuilder = new SearchSourceBuilder();
                    BoolQueryBuilder preQueryBuilder = boolQuery();
                    preQueryBuilder.filter(termQuery("corpid.keyword",workReportListDTO.getCorpid()));
                    preQueryBuilder.filter(termQuery("del",0));
                    preQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_WORK_REPORT.getType()));
                    SearchRequest perSearchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_WORK_REPORT.getIndex());
                    List<String> fieldList = Arrays.asList(FieldTypeEnum.DATAID.getAlias());
                    // 重新排序，取最近的工作报告
                    Collections.sort(reportIdIn,Collections.reverseOrder());
                    int count = reportIdIn.size();
                    int start = 0;
                    int pageNum = 1000;
                    // 超过1000条，分页查询
                    for (; start <= count; start = start + pageNum) {
                        // 分组数据的endIndex
                        int endIndex = (start + pageNum) <= count ? start + pageNum : count;
                        List<Long> queryDataIds = reportIdIn.subList(start, endIndex);
                        preQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(),queryDataIds));

                        preSourceBuilder.query(preQueryBuilder);
                        PageRequest perPageRequest = EsUtil.setPage(preSourceBuilder, start, pageNum);
                        perSearchRequest.source(preSourceBuilder);
                        EsUtil.setFieldList(preSourceBuilder, fieldList);
                        XbbAggregatedPage<PaasFormDataEntityExt> perEsEntities = xbbElasticsearchRestTemplate.queryForPages(perPageRequest, perSearchRequest, PaasFormDataEntityExt.class);
                        if (perEsEntities == null) {
                            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
                        }
                        for (PaasFormDataEntityExt dataEntityExt : perEsEntities.getContent()) {
                            dataIdList.add(dataEntityExt.getDataId());
                        }
                    }

                    // 数据id倒序
                    Collections.sort(dataIdList,Collections.reverseOrder());
                    // 骚操作，超过1000条，只取前1000条
                    if (dataIdList.size() == BasicConstant.ZERO) {
                        dataIdList.add(-1L);
                    } else if (dataIdList.size() > 1000) {
                        dataIdList = dataIdList.subList(0, 1000);
                    }
                    if (shuoldDataId) {
                        boolQueryBuilder.should(termsQuery(FieldTypeEnum.DATAID.getAlias(),dataIdList));
                    } else {
                        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(), dataIdList));
                    }
                }
            }

        }



        String nameLike = workReportListDTO.getNameLike();
        if (nameLike != null && !StringUtil.isEmpty(nameLike, true)) {
            boolQueryBuilder.filter(matchPhraseQuery("data." + WorkReportFieldEnum.CONTENT.getAttr(), nameLike));
        }
        if (StringUtil.isNotEmpty(workReportListDTO.getCreatorId())){
            boolQueryBuilder.filter(termQuery(WorkReportFieldEnum.CREATOR_ID.getAttr() + ".keyword", workReportListDTO.getCreatorId()));
        }
        boolQueryBuilder.filter(termQuery("corpid.keyword",workReportListDTO.getCorpid()));
        boolQueryBuilder.filter(termQuery("del",0));
        if (workReportListDTO.getType() != null){
            boolQueryBuilder.filter(termQuery("data." + WorkReportFieldEnum.TYPE.getAttr(),workReportListDTO.getType().toString()));
        }
        //是否是全部工作报告列表
        if (!Objects.equals(workReportListDTO.getFormId(), 0L) && Objects.nonNull(workReportListDTO.getFormId())) {
            //不是全部列表
            boolQueryBuilder.filter(termQuery("formId",workReportListDTO.getFormId()));
        }
        if (workReportListDTO.getReportDate() != null && !workReportListDTO.getReportDate().isEmpty()){
            boolQueryBuilder.filter(rangeQuery("data." +  WorkReportFieldEnum.REPORT_DATE.getAttr()).gte(DateUtil.getInt(workReportListDTO.getReportDate().get(0).toString(),new SimpleDateFormat("yyyy-MM-dd"))).lt(DateUtil.getInt(workReportListDTO.getReportDate().get(1).toString(),new SimpleDateFormat("yyyy-MM-dd")) + TimeConstant.SECONDS_PER_DAY));
        }
        if (CollectionsUtil.isNotEmpty(workReportListDTO.getConditions())){
            EsUtil.parseCondition(boolQueryBuilder,workReportListDTO.getConditions(),"",corpid,XbbRefTypeEnum.WORK_REPORT.getCode());
        }

        //工作报告
        PaasFormExplainEntity paasFormExplainEntity;
        if (Objects.equals(workReportListDTO.getFormId(), 0L) || Objects.isNull(workReportListDTO.getFormId())) {
            paasFormExplainEntity = paasFormExplainModel.getWorkReportDefaultAllListExplain();
            if (Objects.isNull(paasFormExplainEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
        } else {
            Map<String, Object> paramMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            paramMap.put(ParameterConstant.FORMID, workReportListDTO.getFormId());
            paramMap.put(ParameterConstant.CORPID, corpid);
            paramMap.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            List<PaasFormExplainEntity> list = paasFormExplainModel.list(paramMap);
            if (list == null || list.isEmpty()) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            paasFormExplainEntity = list.get(0);
        }
        List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(explainList.size());
        explainList.forEach((item) -> {
            explainMap.put(item.getAttr(), item);
        });
        //排序
        String sortField = "updateTime";
        FormDataListDTO formDataListDTO = new FormDataListDTO();
        BeanUtil.copyProperties(workReportListDTO,formDataListDTO);
        //字段排序
        Map<String, String> sortMap = businessListHelp.getSortMap(formDataListDTO.getSubBusinessType(), formDataListDTO.getBusinessType(), formDataListDTO.getFormId(), formDataListDTO.getAppId(), formDataListDTO.getCorpid(), formDataListDTO.getListGroupId(), formDataListDTO.getUserId(), formDataListDTO.getSortMap());
        formDataListDTO.setSortMap(sortMap);
        workReportListDTO.setSortMap(formDataListDTO.getSortMap());
        sortMap = workReportListDTO.getSortMap();
        if (sortMap != null && sortMap.size() > 0) {
            SortOrder order = SortOrder.ASC;
            if(SortOrder.DESC.toString().equals(sortMap.get("sort"))){
                order = SortOrder.DESC;
            }
            sortField = (StringUtil.isEmpty(sortMap.get("field")) ? sortField : sortMap.get("field"));
            if(explainMap.containsKey(sortField)) {
                String raw = ".raw";
                FieldAttrEntity sortFieldEntity = explainMap.get(sortField);
                FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(sortFieldEntity.getFieldType());
                if (FieldTypeEnum.TEXT.getEsalias().equals(fieldTypeEnum.getEsalias())) {
                    sortField = sortField + raw;
                }
                //系统字段不用加data.
                if (!BelongEnum.SYSTEM.getAlias().equals(fieldTypeEnum.getBelong())) {
                    sortField = "data." + sortField;
                } else if (Objects.equals(fieldTypeEnum.getType(), FieldTypeEnum.SERIALNO.getType()) && !sortField.contains(fieldTypeEnum.getAlias())) {
                    sortField = "data." + sortField;
                }
            }
            sourceBuilder.sort(new FieldSortBuilder(sortField).order(order));
        } else {
            // web端默认报告日期降序
            String sortStr = Objects.equals(workReportListDTO.getPlatform(), PlatFormEnum.WEB.getValue()) ? "data." + WorkReportFieldEnum.REPORT_DATE.getAttr() : "updateTime" ;
            sourceBuilder.sort(new FieldSortBuilder(sortStr).order(SortOrder.DESC));
        }
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, IndexTypeEnum.IDX_SAAS_WORK_REPORT.getType()));
        sourceBuilder.query(boolQueryBuilder);
        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_WORK_REPORT.getIndex());
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, workReportListDTO.getPage(), workReportListDTO.getPageSize());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
        if (esEntities == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return esEntities;
    }

    /**
     * 设置范围筛选
     * 重构前 -> com.xbongbong.saas.service.impl.WorkReportServiceImpl#rangeScreen(com.xbongbong.pro.weblist.pojo.dto.WorkReportListDTO)
     * @param workReportListDTO
     */
    private ConditionsEntityExt rangeScreen(WorkReportListDTO workReportListDTO) throws XbbException {
        if (Objects.equals(workReportListDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue())) {
            return null;
        }
        JSONObject rangeScreen = workReportListDTO.getRangeScreen();
        if (Objects.isNull(rangeScreen) || Objects.isNull(rangeScreen.get(RangeScreenConstant.TYPE)) || StringUtil.isEmpty(rangeScreen.getString(RangeScreenConstant.TYPE)) || Objects.isNull(rangeScreen.get(RangeScreenConstant.VALUE))) {
            return null;
        }

        String type;
        List<String> values;
        try {
            type = rangeScreen.getString(RangeScreenConstant.TYPE);
            values = rangeScreen.getJSONArray(RangeScreenConstant.VALUE).toJavaList(String.class);
        } catch (Exception e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001.getCode(), "customerCommunicateServiceimpl.rangeScreen中的commonFilter参数错误");
        }
        if (CollectionsUtil.isEmpty(values)) {
            return null;
        }
        if (Objects.equals(type, RangeScreenConstant.DEPARTMENT)) {
            List<Long> deptIds = new ArrayList<>(values.size());
            values.forEach(item -> deptIds.add(Long.valueOf(item)));
            values = userModel.getUserIdsRecursionDep(deptIds, workReportListDTO.getCorpid(), 1, true);
        }
        return new ConditionsEntityExt(WorkReportFieldEnum.CREATOR_ID.getAttr(), "",
                WorkReportDailyEnum.CREATOR_ID.getFieldType(), ConditionEnum.IN.getSymbol(), new ArrayList<>(values));
    }

    /**
     * 获取数据前置处理
     * @param workReportListDTO
     */
    private void beforeGetDataHandle(WorkReportListDTO workReportListDTO) throws XbbException {
        UserEntity userEntity = userModel.getByKey(workReportListDTO.getUserId(),workReportListDTO.getCorpid());
        // app端范围筛选
        saasListDataPermissionHelp.dingtalkRangeScreen(workReportListDTO.getConditions(), userEntity, XbbRefTypeEnum.WORK_REPORT.getCode(), XbbRefTypeEnum.WORK_REPORT.getCode(), workReportListDTO.getPlatform());
        //通用范围筛选
        ConditionsEntityExt conditionsEntityExt = rangeScreen(workReportListDTO);
        if (conditionsEntityExt != null) {
            workReportListDTO.getConditions().add(rangeScreen(workReportListDTO));
        }
    }

    @Override
    public void checkPermission(WorkReportListDTO workReportListDTO) throws XbbException {
        // 列表展示权限判断：有工作报告查看权限就可以查看，不考虑是否在工作报告使用范围内
        VerifyViewPermissionDTO verifyViewPermissionDTO = new VerifyViewPermissionDTO();
        BeanUtil.copyProperties(workReportListDTO, verifyViewPermissionDTO);
        ProPermissionHelp.verifyQueryPermission(verifyViewPermissionDTO);
    }

    @Override
    public WorkReportVO getReturnVO(List<WorkReportPojo> workReportPojoList,long totalElements, Integer page, Integer pageSize, ButtonPermissionPojo buttonPermissionPojo) {
        WorkReportVO workReportVO = new WorkReportVO();
        workReportVO.setList(workReportPojoList);
        PageHelper pageHelper = new PageHelper(page, pageSize);
        pageHelper.setRowsCount((int) totalElements);
        workReportVO.setPageHelper(pageHelper);
        workReportVO.setTopPermissions(buttonPermissionPojo.getTopPermissions());
        return workReportVO;
    }


    /**
     * 封装权限按钮
     * @return
     */
    private ButtonPermissionPojo handlePermissionButton(Integer businessType, UserVO loginUser, UserEntity userEntity) {
        ButtonPermissionPojo buttonPermissionPojo = new ButtonPermissionPojo();
        List<ListTopButtonEnum> topButtonEnumList = ListTopButtonEnum.getByBusinessType(XbbRefTypeEnum.WORK_REPORT.getCode());
        List<ButtonPojo> topButtonList = new ArrayList<>();
        WorkReportSetVisibleRange workReportSetVisibleRange = workReportHelp.getVisibleRange(userEntity);
        Map<String,Boolean> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put(WorkReportEnum.WORKREPORT_DAILY.getAlias(),workReportSetVisibleRange.getDayEnable());
        map.put(WorkReportEnum.WORKREPORT_WEEKLY.getAlias(),workReportSetVisibleRange.getWeekEnable());
        map.put(WorkReportEnum.WORKREPORT_MONTHLY.getAlias(),workReportSetVisibleRange.getMonthEnable());
        Set<String> permSet = loginUser.getPermSet();
        for (ListTopButtonEnum topButtonEnum : topButtonEnumList){
            ButtonPojo buttonPojo = new ButtonPojo();
            BeanUtil.copyProperties(topButtonEnum.getAnEnum(),buttonPojo);
            if (Objects.equals(topButtonEnum.getAnEnum(), SaasButtonEnum.ADD)){
                if (!permSet.contains(ProPermissionAliasEnum.WORK_REPORT_ADD.getAlias())) {
                    continue;
                }
                List<ButtonPojo> subButtonList = new ArrayList<>();
                for (WorkReportEnum workReportEnum : WorkReportEnum.values()){
                    if (!map.getOrDefault(workReportEnum.getAlias(),false)){
                        continue;
                    }
                    ButtonPojo subButton = new ButtonPojo();
                    subButton.setAttr(workReportEnum.getAlias());
                    subButton.setValue(workReportEnum.getName());
                    subButtonList.add(subButton);
                }
                buttonPojo.setSubButtons(subButtonList);
            }
            if (Objects.equals(topButtonEnum.getAnEnum(),SaasButtonEnum.EXPORT) && !permSet.contains(ProPermissionAliasEnum.WORK_REPORT_EXPORT.getAlias())){
                continue;
            }
            if (Objects.equals(topButtonEnum.getAnEnum(),SaasButtonEnum.STATISTICS) && !permSet.contains(ProPermissionAliasEnum.WORK_REPORT_STATISTIC.getAlias())){
                continue;
            }
            if (Objects.equals(topButtonEnum.getAnEnum().getAttr(), SaasButtonEnum.EXPORT.getAttr())) {
                List<ButtonPojo> subButtonList = new ArrayList<ButtonPojo>(){{
                    add(new ButtonPojo(){{BeanUtil.copyProperties(topButtonEnum.getAnEnum(), this);}});
                }};
                List<SaasSubButtonEnum> saasSubButtonEnumList = SaasSubButtonEnum.getByPermissionAlias(businessType,topButtonEnum,loginUser.getPermSet());
                saasSubButtonEnumList.forEach(item->{
                    subButtonList.add(new ButtonPojo(){{setAttr(item.getAlias());setValue(item.getName());}});
                });
                buttonPojo.setSubButtons(subButtonList);
            }
            topButtonList.add(buttonPojo);
        }
        buttonPermissionPojo.setTopPermissions(topButtonList);
        return buttonPermissionPojo;

    }

}
